﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace FiveInRow
{
    public partial class Form1 : Form
    {
        int gridLength;
        int gridSize;
        Factory factory = new Factory();

        IChessStatus chessStatus;
        IStrategy strategy;

        bool blackTurn = true;

        public Form1()
        {
            var sizeStr = System.Configuration.ConfigurationSettings.AppSettings["GridSize"];
            gridSize = Convert.ToInt32(sizeStr);
            var lenStr = System.Configuration.ConfigurationSettings.AppSettings["GridLength"];
            gridLength = Convert.ToInt32(lenStr);

            InitializeComponent();

            InitializeGrid(gridSize);

            Dictionary<string, object> chessParam = new Dictionary<string, object>();
            chessParam.Add("rows", gridSize);
            chessParam.Add("cols", gridSize);
            chessStatus = factory.CreateChessStatus(chessParam);
            Dictionary<string, object> straParam = new Dictionary<string, object>();
            straParam.Add("chessSize", gridSize);
            strategy = factory.CreateStrategy(straParam);
        }

        private void InitializeGrid(int size)
        {
            int chestLength = gridLength * gridSize;
            this.Width = chestLength;
            this.Height = chestLength;

            picBox.Visible = true;
            picBox.Width = chestLength;
            picBox.Height = chestLength;
        }

        private void picBox_Paint(object sender, PaintEventArgs e)
        {
            var graphic = e.Graphics;
            Pen pen = new Pen(Color.Black, 1);
            for (int i = 1; i < 10; ++i)
            {
                //Horizontal line
                Point start = new Point(0, i * gridLength);
                Point end = new Point(picBox.Width, i * gridLength);
                graphic.DrawLine(pen, start, end);

                //Vertical line
                start = new Point(i * gridLength, 0);
                end = new Point(i * gridLength, picBox.Height);
                graphic.DrawLine(pen, start, end);
            }

            //draw black pieces
            var blackPieces = chessStatus.GetBlackPieces();
            if (blackPieces.Count()>0)
            {
                Brush brush = new SolidBrush(blackPieces.First().PieceColor);
                foreach (var black in blackPieces)
                {
                    var piece = black;
                    graphic.FillEllipse(brush, piece.Column * gridLength, piece.Row * gridLength, gridLength, gridLength);
                }
            }

            //draw white pieces
            var whitePieces = chessStatus.GetWhitePieces();
            if (whitePieces.Count() > 0)
            {
                Brush brush = new SolidBrush(whitePieces.First().PieceColor);
                foreach (var white in whitePieces)
                {
                    var piece = white;
                    graphic.FillEllipse(brush, piece.Column * gridLength, piece.Row * gridLength, gridLength, gridLength);
                }
            }
        }

        private Point RowColumn(Point p)
        {
            return new Point(p.X / gridLength, p.Y / gridLength);
        }

        private void picBox_MouseClick(object sender, MouseEventArgs e)
        {
            Point rowColumn = RowColumn(e.Location);

            var piece = CreateBlackPiece(rowColumn.Y, rowColumn.X);
            chessStatus.AddBlackPiece(piece);
            picBox.Invalidate();

            if (chessStatus.BlackWin())
            {
                MessageBox.Show("Black win");
            }

            //Add white piece.
            int row=0, col=0;
            strategy.NextPoint(chessStatus, ref row, ref col);
            var whitePiece = CreateWhitePiece(row, col);
            chessStatus.AddWhitePiece(whitePiece);
            picBox.Invalidate();

            if (chessStatus.WhiteWin())
            {
                MessageBox.Show("White win");
            }
        }

        private IPiece CreateBlackPiece(int row,int column)
        {
            Dictionary<string, object> param = new Dictionary<string, object>();
            param.Add("row", row);
            param.Add("col", column);
            param.Add("color", Color.Black);

            return factory.CreatePiece(param);
        }

        private IPiece CreateWhitePiece(int row, int column)
        {
            Dictionary<string, object> param = new Dictionary<string, object>();
            param.Add("row", row);
            param.Add("col", column);
            param.Add("color", Color.Red);

            return factory.CreatePiece(param);
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            if(e.KeyCode==Keys.R)
            {
                //Reset chess.
                Dictionary<string, object> chessParam = new Dictionary<string, object>();
                chessParam.Add("rows", gridSize);
                chessParam.Add("cols", gridSize);
                chessStatus = factory.CreateChessStatus(chessParam);
            }
        }
    }
}
